#include "Hashmap.h"

Valeur* tmpInt(int val){
    Valeur* v = malloc(sizeof(Valeur));
    v->type=ENTIER;
    v->Value.integer=val;
    v->Specific.isConstant=1;
    v->isRes=1;
    return v;
}

Valeur* tmpFloat(float val){
    Valeur* v =malloc(sizeof(Valeur));
    v->type=FLOAT;
    v->Value.integer=val;
    v->Specific.isConstant=1;
    v->isRes=1;
    return v;
}

Valeur* tmpBool(int val){
    Valeur* v =malloc(sizeof(Valeur));
    v->type=BOOL;
    v->Value.boolean=val;
    v->Specific.isConstant=1;
    v->isRes=1;
    return v;
}

int hashFunc(char *chaine){
    int i;
    int val=0;
    for(i=0; i<strlen(chaine); ++i){
        val+=chaine[i];
    }
    return val%TAILLE;
}

Valeur* addInTable(Hashmap* map, char *chaine){
    int i;
    int index = hashFunc(chaine);
    Valeur* v = map->next[index];

    if(v==NULL){
        map->next[index]=malloc(sizeof(Valeur));
        map->next[index]->name=(char*)malloc(sizeof(char)*(strlen(chaine)+1));
        memcpy(map->next[index]->name, chaine, strlen(chaine)+1);
        map->next[index]->next = NULL;
        return map->next[index];
    }

    if(strcmp(v->name, chaine)==0)
        return NULL; // Symbole déjà présent

    while(v->next!=NULL){
        if(strcmp(v->next->name, chaine)==0)
            return NULL; // Symbole déjà présent
        v=v->next;
    }

    //string not found, let's add it to our mâchemap
    //ajout map
    v->next=malloc(sizeof(Valeur));
    v=v->next;
    v->name=(char*)malloc(sizeof(char)*(strlen(chaine)+1));
    memcpy(v->name, chaine, strlen(chaine)+1);
    v->next = NULL;
    return v;
}

Valeur* searchInTable(Hashmap* map, char *chaine){
    int i;
    int index = hashFunc(chaine);
    Valeur* v = map->next[index];

    if(v==NULL){
        return NULL; // Symbole non présent
    }

    if(strcmp(v->name, chaine)==0)
        return v;

    while(v->next!=NULL){
        if(strcmp(v->next->name, chaine)==0)
            return v->next;
        v=v->next;
    }

    if(map->isChildScope){
        Valeur* par = searchInTable(map->parentMap,chaine);
        if(par!=NULL) return par;
    }

    return NULL; // Symbole non présent
}

void freeTable(Hashmap *map){
    int i;
    for(i=0; i<TAILLE; ++i){
        Valeur* v = map->next[i];
        while(v!=NULL){
            Valeur* tmp = v;
            v = tmp->next;
            free(tmp->name);
            free(tmp);
        }
    }
}

//parentMap est l'ancienne tête de pile
Hashmap* newScopeTable(Hashmap *parentMap, int isChild){
    Hashmap *map = (Hashmap*)malloc(sizeof(Hashmap));
    map->parentMap = parentMap;
    map->isChildScope = isChild;
    return map;
}
